#include "stdafx.h"
#include "TestUtils.h"
#include "GraphColoringTests.h"
#include "VertexDirectory.h"
#include "Helpers.h"
#include <cstdlib>
#include <iostream>

using namespace std;

void RunGraphColoringTests()
{
	try
	{
		TestUtils::PrintTestResult("Test replacing a vertex",TestReplace());
	TestUtils::PrintTestResult("Test replacing a vertex set",TestCouplesReplace());

		TestUtils::PrintTestResult("Run Switch couples", FillOneGroup2VerticesWithSwitching());
// Insert one vertex, return it as minimal
	TestUtils::PrintTestResult("SingleVertex", GetSingleVertexAsMinimal());

// Insert 2 vertices, get the minimally ranked one
	TestUtils::PrintTestResult("Minimal rank out of 2",GetMinimalRankedVertexOutOf2DifferentRanks());		

// Insert 2 vertices to graph, get them by rank
	TestUtils::PrintTestResult("2 vertices" , GetMinimalRankedVertexTwice());

// Get NULL from empty graph
	TestUtils::PrintTestResult("NULL as vertex" , GetVertexFromEmptyGraph());

// Add group to graph and verify
	TestUtils::PrintTestResult("Add group", AddGroupToGraph());

// create a vertex, check it has all the neighbours it should
	TestUtils::PrintTestResult("Check vertex neighbours", CheckVertexNeighbours());

// add and remove neighbours and check that the lists and ranks are updated
	TestUtils::PrintTestResult("Check vertex neighbours remove & add", RemoveAndAddNeighbour());

// create a group and change it
	TestUtils::PrintTestResult("Group create and change", createAndChangeGroup());

// create a Group and break it
	TestUtils::PrintTestResult("check group breaking", testBreakGroup());

// move vertices from the graph to a group and make sure they and their neighbours are updated
	TestUtils::PrintTestResult("Check moving a vertex to a group", MoveVertexToGroup());

	// Test restoring temp group
	TestUtils::PrintTestResult("Check restoring temp group", CheckResettingTempContainer());

// Test getting only couple
	TestUtils::PrintTestResult("Check getting only couple", GetMinimalCouple());

// Create a group and try to fill it useing singles' greedy fill algorithm (without size limitation)
	TestUtils::PrintTestResult("Check greedy fill algorithm for singles without size limitation", FillSingle4On2GroupWithoutSizeLimitation());

// Create a group and try to fill it useing singles' greedy fill algorithm (with size limitation)
	TestUtils::PrintTestResult("Check greedy fill algorithm for singles with size limitation", FillSingle4On2GroupWithSizeLimitation());
	
// Fill an empty group useing singles' greedy fill algorithm (without size limitation)
	TestUtils::PrintTestResult("Check greedy fill algorithm for singles on an empty group, without size limitation", FillSingle4On2EmptyGroupWithoutSizeLimitation());

// Fill an empty group useing singles' greedy fill algorithm (with size limitation)
	TestUtils::PrintTestResult("Check greedy fill algorithm for singles on an empty group, with size limitation", FillSingle4On2EmptyGroupWithSizeLimitation());

// Create a group and try to fill it useing couples' greedy fill algorithm (without size limitation)
	TestUtils::PrintTestResult("Check greedy fill algorithm for couples without size limitation", FillCouples4On2GroupWithoutSizeLimitation());

// Create a group and try to fill it useing couples' greedy fill algorithm (with size limitations)
	TestUtils::PrintTestResult("Check greedy fill algorithm for couples with size limitations", FillCouples4On2GroupWithSizeLimitation());

// Create an empty group and try to improve it useing greedy fill maximal group algorithm
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm on empty group", FillMaximalEmptyGroup4On2());

// Create a group and try to improve it useing greedy fill maximal group algorithm
//	use 10 iterations, start couples' fill when the gtoup is empty, stop it when you've reached twice the size of original group
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, with 10 iterations, and couples fill until we double the group size", FillMaximalGroup4On2(10,0,200));

//	use 3 iterations, start couples' fill when the gtoup is empty, stop it when you've reached half the size of original group
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, with 3 iterations, and couples fill until we reach half the group size", FillMaximalGroup4On2(3,0,50));

// Create a group and try to improve it useing greedy fill maximal group algorithm. The algorithm
// won't use initial filling. Run 1 iteration, fill the group to twice its size with couples fill. this
// will in fact replace the group with a new one.
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, without initial filling (1 iteration)", FillMaximalGroup4On2WithoutInitialFilling(1,0,200));

// Create a group and try to improve it useing greedy fill maximal group algorithm. The algorithm
// won't use initial filling. Run 3 iterations, fill the group to twice its size with couples fill. this
// will in fact replace the group with a new one.
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, without initial filling (3 iterations)", FillMaximalGroup4On2WithoutInitialFilling(3,0,200));

// won't use initial filling. Run 5 iteration, fill the group to 5 times its size with couples fill. this
// will in fact replace the group with a new one.
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, without initial filling (5 iterations)", FillMaximalGroup4On2WithoutInitialFilling(1,0,500));

// won't use initial filling. Run 4 iteration, fill the group up to twice its size with couples fill.
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, without initial filling and without couples fill (4 iterations)", FillMaximalGroup4On2WithoutInitialFillingWithoutCuplesFill(4,200));

// won't use initial filling. Run 2 iteration, fill the group up to 4 times its size with couples fill.
	TestUtils::PrintTestResult("Check greedy fill maximal algorithm, without initial filling and without couples fill (2 iterations)", FillMaximalGroup4On2WithoutInitialFillingWithoutCuplesFill(2,400));

// Runs BreakGroup algorithm on a temporary directory and makes sure the static directory isn't updated
	TestUtils::PrintTestResult("Check BreakGroup algorithm run on a copy or the vertex directory", BreakGroupWithTemporaryDir(6,2));


//	TestUtils::PrintTestResult("check group breaking", testBreakGroup());

// Run the Break&Improve group algorithm on the group 110000,001100: first keep only 55% percent of its vertices (one vertex)
// then keep 30% (no vertices). In both cases should be able to improve the group from 2 vertices to 3
	TestUtils::PrintTestResult("Check BreakGroup algorithm on a 6 on 2 graph. Keep 55% of the group", BreakGroupIn6On2Graph(55));
	TestUtils::PrintTestResult("Check BreakGroup algorithm on a 6 on 2 graph. Keep 30% of the group", BreakGroupIn6On2Graph(30));

// Run the Break&Improve group algorithm with size limitation in different scenarios, with n=6, w=2
//	TestUtils::PrintTestResult("Check BreakGroup algorithm on a 6 on 2 graph, with size limitation on target group", BreakGroupIn6On2GraphWithSizeLimitation());


// Run the BreakAndImproveGroup algorithm on a maximal group ==> won't be able to improve it. Make sure the group remains unchanged
	TestUtils::PrintTestResult("Check BreakGroup algorithm: Validate the group is unchanged if we weren't able to improve it", BreakGroupIn6On2GraphWithoutImprovement());
	
// Run the BreakAndImproveGroup algorithm on a group keeping 100% of its vertices, validate it was improved
	TestUtils::PrintTestResult("Check BreakGroup algorithm when keeping 100% of the original vertices", BreakGroupIn6On2GraphWithoutBreaking());
// Check is legal scenarions with switching
	TestUtils::PrintTestResult("Check is legal for interchangeable that cannot be replaced",TestIsLegalForInterchangeableThatCannotBeReturnedOrReplaced());
	TestUtils::PrintTestResult("Check is legal for interchangeable set that cannot be replaced",TestIsLegalForInterchangeableSetThatCannotBeReturnedOrReplaced());

	TestUtils::PrintTestResult("Check is legal for replacement vertex that has to replace its interchangeable",TestIsLegalForReplacementThatIsRequiredForInterchangeable());
	TestUtils::PrintTestResult("Check is legal for replacement vertex set that has to replace its interchangeable",TestIsLegalForReplacementSetThatIsRequiredForInterchangeableSet());

	TestUtils::PrintTestResult("Check is legal for last replacement vertex that doesn't have to replace its interchangeable",TestIsLegalForLastReplacementThatIsNotRequiredForInterchangeable());
	TestUtils::PrintTestResult("Check is legal for last replacement vertex set that doesn't have to replace its interchangeable",TestIsLegalForLastReplacementThatIsNotRequiredForInterchangeableSet());
	
	TestUtils::PrintTestResult("Check is legal for vertex whose neighbour is a last replacement that must be used",TestIsLegalForVertexThatRuinsReplacements());
	TestUtils::PrintTestResult("Check is legal for vertex set whose neighbour is a last replacement that must be used",TestIsLegalForVertexSetThatRuinsReplacements());
	
	TestUtils::PrintTestResult("Check is legal for vertex that causes 2 interchangeables to use same replacement",TestIsLegalForVertexWithSingleReplacementFor2Vertices());
	TestUtils::PrintTestResult("Check is legal for vertex  set that causes 2 interchangeable sets to use same replacement",TestIsLegalForVertexSetWithSingleReplacemenSetFor2Vertices());
	
	
	
	
// Check switching algorithm
	TestUtils::PrintTestResult("Fill empty chain by switching", FillEmptyChain());

	TestUtils::PrintTestResult("Fill chain with one group with one vertex by switching", FillOneGroupOneVertexWithSwitching());
		
	TestUtils::PrintTestResult("Run 2 iterations of switching starting from empty", Run2IterationsOfSwitchingStartingFromEmpty());
	
	TestUtils::PrintTestResult("Run Switch singles on colored graph", RunSwitchingOnFullColoring());

		
	// various scenariou dealing with chain comparison
	// compare chains with the same length
	TestUtils::PrintTestResult("Compare chains with same lengths", CompareBiggerAndSmallerChains());

	//compare identical chains
	TestUtils::PrintTestResult("Compare identical chains", CompareIdenticalChains());

	// compare chains with identical group sizes but different groups
	TestUtils::PrintTestResult("Compare equal chains", CompareEqualChains());

	// compare chains with the same number of total vertices, but one is better than the other
	TestUtils::PrintTestResult("Compare similar non equal chains", CompareSimilarNonEqualChains());

	// compare chains when the better chain is shorter
	TestUtils::PrintTestResult("Compare short bigger chain to long smaller one", CompareSmallerLongerChain());

	// compare chains when the better chain is longer
	TestUtils::PrintTestResult("Compare long bigger chain to short smaller one", CompareBiggerLongerChain());

	}
	catch (GraphColoringException &e)
	{
		Debug::PrintDebugMsg(e.GetErrorDescription());
	}
	
	return; //end run tests
}

